package com.fagertveit.android.game.cb;

import java.util.List;

import android.util.Log;

import com.fagertveit.android.game.framework.geom.AABB;
import com.fagertveit.android.game.framework.geom.Circle;
import com.fagertveit.android.game.framework.geom.Collision;
import com.fagertveit.android.game.framework.geom.Vector2;

public class GameCollision {
	public static Ball wallCollide(Ball ball, AABB[] walls) {
		for(int i = 0; i < walls.length; i++) {
			if(Collision.collide(walls[i], ball.getShape())) {
				ball.stepBack();
				ball.setDir(wallCollision(i, ball.getDir()));
				Log.d("Wall Collision", "Wall " + i + " Collision");
			}
		}
		return ball;
	}
	
	public static Vector2 wallCollision(int wall, Vector2 dir) {
		Vector2 normal;
		if(wall == 0) {
			normal = new Vector2(1.0f, 0.0f);
		} else if(wall == 1) {
			normal = new Vector2(0.0f, -1.0f);
		} else {
			normal = new Vector2(-1.0f, 0.0f);
		}
		
		
		normal = normal.scale(2*normal.dot(new Vector2(-dir.x, -dir.y)));
		normal = normal.add(dir);
		normal.nor();
		return normal;
	}
	
	public static Ball padCollide(Pad pad, Ball ball) {
		if(Collision.collide(pad.getShape(), ball.getShape())) {
			ball.setDir(padCollision(pad.getShape(), ball.getShape()));
			ball.stepBack();
		}
		return ball;
	}
	
	public static Vector2 padCollision(AABB pad, Circle ball) {
		Vector2 circleVector, padVector, normal;
		
		circleVector = ball.pos.copy();
		padVector = new Vector2(pad.pos.x, pad.pos.y - pad.width);
		
		normal = padVector.sub(circleVector).copy();
		normal.x = -normal.x;
		normal.nor();
		
		Log.d("Pad Collision", "Normal Vector x: " + normal.x + " y: " + normal.y);
		
		return normal;
	}
	
	public static Ball brickCollide(Ball ball, Level level) {
		List<RectangularBrick> bricks = level.getBricks();
		for(int i = 0; i < bricks.size(); i++) {
			if(Collision.collide(bricks.get(i).getShape(), ball.getShape())) {
				ball.setDir(brickCollision(bricks.get(i).getShape(), ball.getShape(), ball.getDir()));
				ball.stepBack();
				bricks.remove(i);
			}
		}
		return ball;
	}
	
	public static Vector2 brickCollision(AABB brick, Circle ball, Vector2 dir) {
		Vector2 normal, corner;
		AABB height = new AABB(brick.pos.x, brick.pos.y, brick.width, brick.height * 2);
		AABB width = new AABB(brick.pos.x, brick.pos.y, brick.width * 2, brick.height);
		
		if(Collision.collide(height, ball.pos)) {
			if(ball.pos.y > brick.pos.y) {
				normal = new Vector2(0.0f, -1.0f);
			} else {
				normal = new Vector2(0.0f, 1.0f);
			}
		} else if(Collision.collide(width, ball.pos)) {
			if(ball.pos.x > brick.pos.y) {
				normal = new Vector2(-1.0f, 0.0f);
			} else {
				normal = new Vector2(1.0f, 0.0f);
			}
		} else {
			if(ball.pos.x > brick.pos.x) {
				if(ball.pos.y > brick.pos.y) {
					corner = new Vector2(brick.pos.x + brick.width, brick.pos.y + brick.height);
				} else {
					corner = new Vector2(brick.pos.x + brick.width, brick.pos.y - brick.height);
				}
			} else {
				if(ball.pos.y > brick.pos.y) {
					corner = new Vector2(brick.pos.x - brick.width, brick.pos.y + brick.height);
				} else {
					corner = new Vector2(brick.pos.x - brick.width, brick.pos.y - brick.height);
				}
			}
			corner = corner.sub(ball.pos);
			corner.nor();
			normal = corner;
		}
		
		normal = normal.scale(2*normal.dot(new Vector2(-dir.x, -dir.y)));
		normal = normal.add(dir);
		normal.nor();
		
		return normal;
	}
}
